package com.hwy.chart.coordinate.axis

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import androidx.annotation.IntDef

/**
 * =======================================
 * 作者: hewenyu
 * 日期: 2022/5/10 18:44
 * 说明: 坐标轴标签
 * =======================================
 */
open class AxisTag {

    companion object {

        /**
         * 坐标轴文本显示在内测
         *
         * 纵轴: 显示在坐标轴右侧
         * 横轴: 显示在坐标轴上侧
         */
        const val MODEL_INNER = 1

        /**
         * 坐标轴文本显示在外侧
         *
         * 纵轴: 显示在坐标轴左侧
         * 横轴: 显示在坐标轴下侧
         */
        const val MODEL_OUTER = 2

        @IntDef(MODEL_INNER, MODEL_OUTER)
        annotation class AxisModel

        /**
         * tag数量小于当前值时，不绘制
         */
        private const val MIN_TAG_SIZE = 2

    }

    /**
     * 坐标轴上的标签列表
     */
    private val dataList by lazy {
        ArrayList<String>()
    }

    private val tagPaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
        }
    }

    /**
     * 坐标轴文本大小
     */
    var tagTextSize = 16F

    /**
     * 坐标轴文本颜色
     */
    var tagTextColor = Color.GRAY

    /**
     * 坐标轴显示的位置
     */
    @AxisModel
    var axisModel = MODEL_OUTER

    /**
     * 坐标轴文本距离坐标轴的偏移量
     */
    var axisOffset = 0

    fun clearTags() {
        dataList.clear()
    }

    open fun addTag(tag: String) {
        dataList.add(tag)
    }

    open fun addTagList(list: ArrayList<String>?) {
        clearTags()
        list?.run {
            dataList.addAll(this)
        }
    }

    /**
     * 绘制坐标轴标签
     *
     * @param orientation [BaseAxis.VERTICAL]表示纵轴、[BaseAxis.HORIZONTAL]表示横轴
     * @param coordinate 横轴时表示横轴显示的y坐标，纵轴时表示纵轴显示的x坐标
     */
    open fun draw(
        canvas: Canvas,
        bounds: RectF,
        @BaseAxis.Companion.Orientation orientation: Int,
        coordinate: Float
    ) {
        if (dataList.size < MIN_TAG_SIZE) {
            return
        }
        if (orientation == BaseAxis.VERTICAL) {
            drawVerticalTag(canvas, bounds, coordinate)
        } else {
            drawHorizontalTag(canvas, bounds, coordinate)
        }
    }

    /**
     * 绘制横轴的tag
     *
     * @param yCoordinate 横轴显示的y坐标
     */
    protected open fun drawHorizontalTag(canvas: Canvas, bounds: RectF, yCoordinate: Float) {
        tagPaint.run {
            textSize = tagTextSize
            color = tagTextColor
        }
        // 计算步长
        val step = bounds.width() / (dataList.size - 1)
        // tag绘制的x位置
        var tagX = bounds.left
        dataList.forEachIndexed { index, tag ->
            tagPaint.textAlign = when (index) {
                0 -> Paint.Align.LEFT
                dataList.size - 1 -> Paint.Align.RIGHT
                else -> Paint.Align.CENTER
            }
            val y = if (axisModel == MODEL_INNER) {
                // 绘制在横轴上方
                yCoordinate - axisOffset - tagPaint.fontMetrics.bottom
            } else {
                // 绘制在横轴下方
                yCoordinate + axisOffset - tagPaint.fontMetrics.top
            }
            // 绘制标签文本
            canvas.drawText(tag, tagX, y, tagPaint)
            tagX += step
        }
    }

    /**
     * 绘制纵轴的tag
     */
    protected open fun drawVerticalTag(canvas: Canvas, bounds: RectF, xCoordinate: Float) {
        tagPaint.run {
            textSize = tagTextSize
            color = tagTextColor
        }
        // 计算步长
        val step = bounds.height() / (dataList.size - 1)
        // tag绘制的y位置
        var tagY = bounds.bottom
        dataList.forEachIndexed { index, tag ->
            tagPaint.textAlign = if (axisModel == MODEL_INNER) {
                Paint.Align.LEFT
            } else {
                Paint.Align.RIGHT
            }

            var y = bounds.bottom - step * index
            if (index == dataList.size - 1) {
                // 最顶上的一个数据tag显示在下方
                y += (axisOffset - tagPaint.fontMetrics.top)
            } else {
                y -= (axisOffset + tagPaint.fontMetrics.bottom)
            }

            // 绘制标签文本
            canvas.drawText(tag, xCoordinate, y, tagPaint)
            tagY -= step
        }
    }

}